import os
import time

from Demos.win32ts_logoff_disconnected import username
from sqlmap.thirdparty.bottle.bottle import response

from middle.user import generate_token, verify_token, public_key, private_key
from flask import Flask, render_template, request, jsonify, send_from_directory, redirect, url_for, send_file
from database import Base, engine, SessionLocal
from model.model import *
from util import send_netease_verification, password_hash, verify_password
from datetime import datetime
app = Flask(__name__)

VerificationCode_email = {}

tags_chinese = {
    'string' : '字符串',
    'array' : '数组',
    'dp' : '动态规划',
    'tree' : '树',
    'graph' : '图',
    'union' : '并查集',
    'diff' : '前缀和',
    'window' : '滑动窗口',
    'double' : '双指针',
    'hash' : '哈希表',
    'stack' : '栈',
    'queue' : '队列',
    'dfs' : '深度优先搜索',
    'bfs' : '广度优先搜索',
    'segment' : '线段树',
    'treenums' : '树状数组',
    'topo' : '拓扑排序',
    'sort' : '排序',
    'binary' : '二分查找',
    'bit' : '位运算',
    'bits' : '状态压缩',
    'tanxin' : '贪心',
    'backtrack' : '回溯'
}

@app.route('/')
def hello_world():  # put application's code here
    return render_template('index.html')

@app.route('/index')
def index():
    return render_template('index.html')


@app.route('/home')
def home():
    return 'Hello World!'

@app.route('/test')
def test():
    return 'This is a test route'

@app.route('/questions/<id>')
def question(id):
    db = SessionLocal()
    question = db.query(Question).filter_by(id=id).first()
    solution = db.query(Solution).filter_by(question_id=id).first()
    if question:
        return render_template('question.html', question=question, solution=solution)
    else:
        return 'Question not found', 404


@app.route('/questions')  # 前端跳转的URL路径（可自定义）
def questions():  # 函数名必须是 "questions"，与前端 url_for 对应
    return render_template('questions.html')  # 题库页面的HTML文件

@app.route('/contests')
def contests():  # 函数名必须是 "contests"
    return render_template('contests.html')

@app.route('/ranking')
def ranking():  # 函数名必须是 "ranking"
    return render_template('ranking.html')

@app.route('/resources')
def resources():  # 函数名必须是 "resources"
    return render_template('resources.html')

@app.route('/profile/<id>')
def profile(id):  # 函数名必须是 "profile"
    db = SessionLocal()
    user = db.query(User).filter_by(id=id).first()
    if user:
        return render_template('profile.html', id=id, user=user)
    else:
        return 'User not found', 404

@app.route('/my_progress/<id>')
def my_progress(id):  # 函数名必须是 "my_progress"
    db = SessionLocal()
    user = db.query(User).filter_by(id=id).first()
    if user:
        return render_template('my_progress.html', id=id, user=user)
    else:
        return 'User not found', 404

@app.route('/login')
def login():
    return render_template('login.html')

@app.route('/register')
def register():
    return render_template('register.html')

@app.route('/favorites/<id>')
def favorites(id):
    db = SessionLocal()
    user = db.query(User).filter_by(id=id).first()
    if user:
        return render_template('favorites.html', id=id, user=user)
    else:
        return 'User not found', 404

@app.route('/notes/<id>')
def notes(id):
    db = SessionLocal()
    user = db.query(User).filter_by(id=id).first()
    if user:
        return render_template('notes.html', id=id, user=user)
    else:
        return 'User not found', 404

@app.route('/solutions/<id>')
def solutions(id):
    db = SessionLocal()
    solution = db.query(Solution).filter_by(question_id=id).first()
    if solution:
        return render_template('solutions.html', id=id, solution=solution)
    else:
        return 'Solution not found', 404

@app.route('/ebooks/<id>')
def ebooks(id):
    db = SessionLocal()
    user = db.query(User).filter_by(id=id).first()
    if user:
        return render_template('ebooks.html', id=id, user=user)
    else:
        return 'User not found', 404

@app.route('/projects/<id>')
def projects(id):
    db = SessionLocal()
    user = db.query(User).filter_by(id=id).first()
    if user:
        return render_template('projects.html', id=id, user=user)
    else:
        return 'User not found', 404

@app.route('/courses/<id>')
def courses(id):
    db = SessionLocal()
    user = db.query(User).filter_by(id=id).first()
    if user:
        return render_template('courses.html', id=id, user=user)
    else:
        return 'User not found', 404

# api
@app.route('/api/v1/logout', methods=['POST'])
def logout_api():
    token = request.headers.get('Authorization', '').replace('Bearer ', '')
    if not token:
        return jsonify({'code': 401, 'message': '未登录'})

    result = verify_token(token, public_key)
    if result['valid']:
        db = SessionLocal()
        try:
            user = db.query(User).filter_by(id=result['user_id']).first()
            user.token = ''
            db.commit()
            return jsonify({'code': 200, 'message': '退出成功'})
        finally:
            db.close()
    else:
        return jsonify({'code': 401, 'message': '未登录'})


@app.route('/api/v1/login', methods=['POST'])
def login_api():
    email = request.json.get('email')
    # print(email)
    password = request.json.get('password')

    db = SessionLocal()
    try:
        # 3. 执行查询（核心：通过 session.query(模型)）
        # 等价于 SQL：SELECT * FROM users WHERE username='xxx' AND password='xxx' LIMIT 1
        user = db.query(User).filter_by(
            email=email,
        ).first()

        # 4. 处理查询结果
        if user:
            if verify_password(password, user.password):
                return jsonify({"code": 200, "message": "登录成功", "token": generate_token(user.id, private_key)})
            else:
                return jsonify({"code": 401, "message": "密码错误"})
        else:
            return jsonify({"code": 404, "message": "用户不存在"})

    finally:
        # 5. 关闭会话（必须执行，避免数据库连接泄漏）
        db.close()

@app.route('/api/v1/VerificateCode', methods=['POST'])
def VerificateCode_api():
    email = request.json.get('email')
    code = send_netease_verification(email)
    if code:
        VerificationCode_email[email] = {"code": code, "time": time.time()}
        return jsonify({"code": 200, "message": "验证码发送成功"})
    else:
        return jsonify({"code": 500, "message": "验证码发送失败"})


@app.route('/api/v1/register', methods=['POST'])
def register_api():
    username = request.json.get('username')
    password = request.json.get('password')
    email = request.json.get('email')
    verificationCode = request.json.get('verificationCode')
    password = password_hash(password)

    if email not in VerificationCode_email:
        return jsonify({"code": 500, "message": "验证码错误"})

    if verificationCode != VerificationCode_email[email]["code"]:
        return jsonify({"code": 500, "message": "验证码错误"})

    if time.time() - VerificationCode_email[email]["time"] > 300:
        return jsonify({"code": 500, "message": "验证码已过期"})

    db = SessionLocal()
    try:
        user = User(
            username=username,
            password=password,
            email=email,
            photos="static/avatar/1.jpg",
            create_time=datetime.now(),
            update_time=datetime.now(),
        )
        db.add(user)
        db.commit()

        questions = db.query(Question).all()
        for question in questions:
            db.add(Solution(
                user_id=user.id,
                question_id=question.id,
                state=SolutionState.NOTSTART,
            ))
        db.commit()
        return jsonify({"code": 200, "message": "注册成功"})
    finally:
        db.close()

@app.route('/api/check_login')
def check_login():
    # 从 Cookie 或请求头获取 Token（根据实际存储方式选择）
    # print(request.cookies)
    # token = request.cookies.get('token')  # 从 Cookie 获取
    token = request.headers.get('Authorization', '').replace('Bearer ', '')
    # print(token)
    if not token:
        return jsonify({'is_logged_in': False})  # 无 Token，未登录

    # 验证 Token
    result = verify_token(token, public_key)
    # print(result)
    if result['valid']:

        db = SessionLocal()
        user = db.query(User).filter_by(id=result['user_id']).first()
        return jsonify({
            'is_logged_in': True,
            'user_id': result['user_id'],
            'username': user.username,
            'email': user.email,
            'avatar': user.photos,
        })
    else:
        return jsonify({'is_logged_in': False})


@app.route('/api/v1/user_info', methods=['GET'])
def user_info_api():
    token = request.headers.get('Authorization', '').replace('Bearer ', '')
    if not token:
        return jsonify({'code': 401, 'message': '未登录'})

    result = verify_token(token, public_key)
    if result['valid']:
        db = SessionLocal()
        try:
            user = db.query(User).filter_by(id=result['user_id']).first()
            completed_questions_cnt = db.query(Solution).filter_by(user_id=user.id, state=SolutionState.FINISH).count()
            total_questions_cnt = db.query(Solution).filter_by(user_id=user.id, state=SolutionState.START).count()+completed_questions_cnt + 1
            return jsonify({'code': 200, 'message': '获取用户信息成功',
                            'username': user.username,
                            'email': user.email,
                            'completed_questions': completed_questions_cnt,
                            'accuracy': completed_questions_cnt/total_questions_cnt*100,
                            'contests_count': 0,
                            'ranking': 0
                            })
        finally:
            db.close()
    else:
        return jsonify({'code': 404, 'message': 'token无效'})


@app.route('/api/v1/Getquestion', methods=['POST'])
def Getquestion_api():
    data = request.get_json()
    page = data.get('page')
    page_size = data.get('page_size')
    tags = data.get('tags')
    difficulty = data.get('difficulty')
    status = data.get('status')

    token = request.headers.get('Authorization', '').replace('Bearer ', '')
    if not token:
        db = SessionLocal()
        try:
            qs = db.query(Question).filter()
            length = qs.count()
            qs = qs.offset((page - 1) * page_size).limit(page_size).all()
            questions = []
            for question in qs:
                solve_cnt = db.query(Solution).filter_by(question_id=question.id, state=SolutionState.FINISH).count()

                questions.append({
                    'id': question.id,
                    'title': question.title,
                    'description': question.content,
                    'difficulty': question.difficulty,
                    'tags': [tags_chinese[tag.name] for tag in question.tags],
                    'state': SolutionState.NOTSTART.value,
                    'solved_count': solve_cnt,
                })
            return jsonify({'code': 200, 'message': '获取题目成功', 'questions': questions, 'length': length})
        finally:
            db.close()
    result = verify_token(token, public_key)
    if result['valid']:
        user_id = result['user_id']
    else:
        db = SessionLocal()
        try:
            qs = db.query(Question).filter()
            length = qs.count()
            qs = qs.offset((page - 1) * page_size).limit(page_size).all()
            questions = []
            for question in qs:
                solve_cnt = db.query(Solution).filter_by(question_id=question.id, state=SolutionState.FINISH).count()

                questions.append({
                    'id': question.id,
                    'title': question.title,
                    'description': question.content,
                    'difficulty': question.difficulty,
                    'tags': [tags_chinese[tag.name] for tag in question.tags],
                    'state': SolutionState.NOTSTART.value,
                    'solved_count': solve_cnt,
                })
            return jsonify({'code': 200, 'message': '获取题目成功', 'questions': questions, 'length': length})
        finally:
            db.close()

    questions = []
    db = SessionLocal()
    # print(1)
    try:
        query = db.query(Solution).filter_by(user_id=user_id).join(Question,  Solution.question_id == Question.id)
        # print(query.all())
        if tags:
            query = query.filter(Question.tags.any(Tag.name.in_(tags)))
        if difficulty:
            query = query.filter(Question.difficulty.in_(difficulty))
        if status:
            query = query.filter(Solution.state.in_(status))
        length = query.count()
        solutions = query.offset((page - 1) * page_size).limit(page_size).all()
        for solution in solutions:
            solve_cnt = db.query(Solution).filter_by(question_id=solution.question.id, state = SolutionState.FINISH).count()
            tags = [tags_chinese[tag.name] for tag in solution.question.tags]
            questions.append({
                'id': solution.question.id,
                'title': solution.question.title,
                'description': solution.question.content,
                'difficulty': solution.question.difficulty,
                'tags': tags,
                'state': solution.state.value,
                "solved_count": solve_cnt,
            })
        return jsonify({'code': 200, 'message': '获取题目成功', 'questions': questions, 'length': length})
    finally:
        db.close()


@app.route('/api/v1/avatar/<int:user_id>', methods=['GET'])
def get_avatar(user_id):
    db = SessionLocal()
    try:
        user = db.query(User).filter_by(id=user_id).first()
        if user.photos:
            return send_file(user.photos, mimetype='image/jpeg')
        else:
            return send_file("static/avatar/default.jpg", mimetype='image/jpeg')
    finally:
        db.close()

def check_auth(token):
    if not token:
        return False
    result = verify_token(token, public_key)
    if result['valid']:
        return True
    else:
        return False


if __name__ == '__main__':
    app.run()
